home *** CD-ROM | disk | FTP | other *** search
-
- extensions/extensions extensions/extensions
- extensions/EXTENSIONS extensions/EXTENSIONS
-
- COMPILER EXTENSIONS
-
- AUTO LIBRARY OPENNING
-
- Certain Amiga libraries are supported on an autoinit basis. Normally
- you declare the library base variable then OpenLibrary() it in your
- main.
-
- If you EXTERN the library base variable instead then it will be brought
- in from auto.lib along with autoinit code to automatically
- OpenLibrary() it on startup and CloseLibrary() it on shutdown.
-
- DICE uses this feature to automatically open floating point libraries,
- dos.library, etc... The following libraries may currently be openned
- in this fashion (note that if you attempt to use the feature on a
- library that does not support auto-open a link error will occur):
-
- asl.library (2.0)
- dos.library
- fifo.library
- gadtools.library (2.0)
- graphics.library
- mathffp.library
- mathtrans.library
- mathieeesingbas.library (2.0, works w/ 1.3)
- mathieeesingtrans.library (2.0, works w/ 1.3)
- mathieeedoubbas.library
- mathieeedoubtrans.library
- intuition.library
- layers.library
- utility.library (2.0)
-
- Others will be added in the future, eventually all the libraries.
-
- Note that the auto-open features is fully upward compatible to earlier
- methods of declaring the base pointer and openning the libraries
- manually. Declaring a library base variable causes the associated
- autolib routines to NOT be linked into the executable.
-
- TYPE QUALIFIER AND STORAGER QUALIFIER EXTENSIONS
-
- availability: reg-only = registered users
-
-
- extension avail comment
-
- volatile all force auto's to NOT be placed in registers
- const all place data items in the code section (see -ms/-mS)
- __autoinit all cause a subroutine to be run automatically
- before _main (for variables, puts variable in
- alternate section)
- __autoexit all cause a subroutine to be run automatically
- before _exit
- __interrupt all NOT AMIGA COMPATIBLE
- __chip reg-only cause storage to be placed in CHIP memory
- __far all cause storage to be referenced using absolute-long
- __near all cause storage to be referenced using A4-relative
- __aligned all cause storage to be aligned on a longword boundry
- __unaligned all allows structures to be byte-aligned (at your own risk)
- __geta4 reg-only cause a subroutine to setup the A4 data base
- pointer
-
- __shared all storage is placed in the code section and thus
- is shared between instances of a resident'd
- program. EXPERIMENTAL
-
- __regargs all specify function takes registered arguments
- even if -mr/-mR/-mRR is not used.
-
- __stkargs all specify function takes normal stack based
- args despite the possibility that -mr/-mR/-mRR
- has been specified.
-
- __dynamic reg-only dynamic linking of routines/variables at run-
- time
-
- volatile
- This storage qualifier normally specifies that the physical storage
- is 'synched' at the end of each line of C code. DICE already does
- this by virtue of not doing any major optimizations. Under ANSI
- this storage qualifier also forces auto variables to NOT be placed
- in a register. This can be important if you use <setjmp.h>
- (see MAN/SETJMP.DOC for more information)
-
- const
- The const type qualifier can be handled in different ways by DICE.
- As of the 2.05.11 version of DC1, any const qualified object is
- placed in the code section. Before 2.05.11 const qualified
- objects were only placed in the code section if -ms or -mS was
- also given to DCC.
-
- Normally a const qualified item is handled as a near item (pc-rel)
- within the module that declares it, and handled with absolute-long
- references in modules that extern it.
-
- If -ms is used then string constants are made const. If -mS is
- used then all external references to const items use pc-relative
- instead of the absolute-long addressing mode. Do NOT use -mS
- unless your final code size is less than 32KBytes.
-
- Using -ms can substantially reduce the number of run-time
- relocations for -r residentable programs as well as the run-time
- dynamically allocated data+bss space.
-
- (refer to DCC.DOC, -ms and -mS options for details)
-
- __autoinit
- __autoexit
-
- These storage qualifiers cause a routine to be called after libraries
- are openned before _main is called (__autoinit), and just before
- libraries are closed after _exit is called (__autoexit). They may
- be used for low level initialization and shutdown and may not make
- any c.lib calls (i.e. malloc, fopen, open, etc... may not be called)
-
- __autoinit void
- fubar()
- {
- NewList(&MyList);
- }
-
- __autoinit may be used with a variable declaration. The variable
- is placed in an alternate section. This is mainly of use for
- ROMable applications to group declared data together, with a base
- section pointer in the ROM startup object and a 'terminator'
- in the last object module. For example, a 'ROM MODULE LIST' may
- be constructed painlessly using this feature.
-
- __autoinit int a; /* altbss,bss */
- __autoinit int a = 4; /* altdata,data */
- __autoinit const int a; /* altcode,code */
- __autoinit const int a = 4; /* altcode,code */
-
- SUGGESTION: use dcc -a to oberve the assembly generated. Note
- that BSS data verses INITIALIZED data go into different sections.
-
- __interrupt
-
- This storage qualifier for a subroutine causes all used registers to
- be saved and restored, including the scratch registers, and returns
- via RTE instead of RTS.
-
- THIS KEYWORD IS NOT AMIGA COMPATIBLE
-
- __chip
-
- This storage qualifier forces a static or global data item to be
- placed in CHIP memory. Normally this precludes being able to make
- such programs resident (-r option), but if you also use the -ms
- option and the 'const' type qualifier you can make such programs
- resident.... The 'const' type qualifier assumes that the contents
- of the object will NEVER be modified!!!
-
- __chip short ImageData[] = { ... }; read-write object
- __chip const short ImageData[] = { ... }; read-only object
-
- __far
-
- __far int a;
-
- This storage qualifier determines how a data object is to be
- referenced. It overides the data model for the reference and
- forces the ABSOLUTE-LONG addressing mode to be used.
-
- Note that __chip data is automatically forced to be __far.
- When compiling -mD the default is to use __far references.
-
- __near
-
- __near int a;
-
- This storage qualifier forces a small-data model (A4-Relative)
- reference to a data object. When using the -md (default) data
- model data objects are accessed as near items by default.
-
- __aligned
-
- This storage qualifier forces the static, global, or auto data
- object to be aligned on a longword boundry.
-
- foo()
- {
- __aligned struct FileInfoBlock fib;
- ...
- }
-
- WARNING: __aligned does not work if this subroutine or any
- higher level subroutine is passed a *structure* where said
- structure is not aligned. We are talking about passing actual
- structures here, not pointers to structures (which work fine
- with __aligned).
-
- __unaligned
-
- This storage qualifier allows structures to be byte-aligned in
- terms of NOT padding them to the nearest word or longword.
-
- __unaligned struct foo {
- char a;
- } a, b, c;
-
- In the above example, sizeof(a), sizeof(b), and sizeof(c) is 1.
-
- USE AT YOUR OWN RISK. Accessing word/long/ptr items at odd
- byte addresses is illegal for the 68000 and will generate an
- exception. This qualifier is useful mainly for character
- structures that must map over a text file.
-
- __geta4
-
- This storage qualifier on a subroutine definition forces the
- subroutine to save A4 and then load A4 with the small-data model
- data pointer on subroutine entry, then restore the original
- contents of A4 on subroutine exit. This is useful for
- inter-context calls when using the small-data model.
-
- __geta4 void
- fubar()
- {
-
- }
-
- Unfortunately, using this qualifier precludes being able to
- generate a residentable executable since a residentable
- executable's data space pointer is unknown at link time.
-
- __shared
-
- This storage modifier places the global or static variable
- declaration into the code segment, thus this variable will be
- SHARED across multiple running instances of the same program,
- assuming the program has been made RESIDENT. A program that has
- not been made resident will not share variables.
-
- __config (UNDER TESTING, DO NOT USE FOR ANY REAL PROJECT)
-
- This storage modifier generates loading and saving code for all
- variables in question. You should not declare any pointers as
- a saved pointer value will not be valid when the program is run
- later on.
-
- If no configuration file exists the initialized value of the static
- or global storage is used, for example:
-
- __config int a = 34;
-
- 'a' will be 34 if no configuration file exists. If a configuration
- file does exist all __config variables will be overriden with the
- values stored in the configuration file.
-
- The name and version of the configuration file must be specified
- by the programmer as two initialized global variables or a link
- error will occur. For example:
-
- char *ConfigFile = "s:myprog.config";
- long ConfigVersion = 1;
-
- DICE configuration code will automatically ignore any configuration
- file whos version does not equal ConfigVersion. As a programmer,
- you must change ConfigVersion if you modify ANY __config
- declaration, the ordering of any __config declaration, or the
- ordering of any object modules in your link. If you fail to do so,
- the program may attempt to load an invalid configuration.
-
- The configuration is automatically loaded on program startup,
- before _main() (__main from assembly) gets run, and if ConfigFile
- is non-NULL on program exit (_exit) then the configuration will be
- saved. Thus, __config is supported even if you use the _main()
- entry point and _exit() exit point.
-
- WARNING: ONLY PROCESSES MAY USE THE __CONFIG TYPE QUALIFIER. If
- you plan to run a program as a task instead of a process then you
- cannot use __config. Note that any WORKBENCH or CLI run program
- is a process. DOS handlers are also processes, but it is not
- suggested that __config be used for any program that is to be
- a DOS handler (i.e. a DOS device). Libraries and exec Devices are
- NOT processes... not even tasks usually, and thus __config may not
- be used for such programs.
-
- __regargs
- __stkargs
-
- Normally these qualifiers are used in conjuction with the -mr,
- -mR, or -mRR flags. Even so, they are usually used only to
- force a normal C calling convention for callback functions (when
- you supply intuition, graphics, exec, or whomever with a callback
- function the OS will call you with arguments on the stack).
-
- Specifying neither causes the routine to default to either stack
- args or register args depending on the DCC flags. Specifying
- __stkargs forces the function to use stack based arguments no
- matter what options are used. Specifying __regargs forces the
- function to use register based arguments in the same manner.
- Specifying both forces the function to generate two entry points
- (same thing occurs by default when -mr is used).
-
- Please refer to the discussion in REGARGS.DOC for more information
-
- __dynamic
-
- The __dynamic storage qualifier is used to declare routines that
- do not exist at link or load time but will be loaded run-time.
- The overall effect is to generate autoinit code to dynamically
- load an indirect pointer to the declared variable/procedure and
- autoexit code to release your references on said pointer.
-
- DICE transparently declares the variables/procedures as pointers
- and transparently indirects whenever they are used in code. The
- __dynamic feature is INCREDIBLY POWERFUL, allowing a program to
- interface to third-party object modules at run-time. Generally,
- this type of interface is more desirable than a shared-library
- when the module in question are huge -- do major things, as well
- as allowing third-party replacement of modules without effecting
- program operation or requiring a relinking of the program.
-
- Please refer to DYNAMIC.DOC for a more involved explanation.
-
-
- --------------------------------------------------------------------
-
- DYNAMIC STACKS (-gs option)
-
- DICE now has a new option, -gs, which generates stack checking code for
- every subroutine. But, unlike SAS/C or MANX, DICE is able to allocate
- new stack chunks when the current stack runs out. Essentially this
- means that you can compile and run programs which expect a lot of stack
- without having to remember to give a larger STACK command in your
- CLI. Since DICE allocates and deallocates stack chunks according to
- program usage, an efficient use of the amiga's memory is made.
-
- There are two global variables associated with this option. You, the
- programmer, may override either or both of them by declaring them
- yourself. The variables are:
-
- long _stack_fudge = 4096;
- long _stack_chunk = 32768;
-
- The defaults are shown above. You can modify these variables either
- by declaring them globally or changing them on the fly (usually from
- main()).
-
- _stack_fudge specifies the minimum amount of stack before DICE creates
- a new stack. This should be AT LEAST 2048 BYTES! This parameter MUST
- be able to handle the worst case stack usage for any given subroutine.
-
- The second parameter specifies the chunk size for any new stacks
- created. A new stack is created whenever the current available
- stack goes below _stack_fudge, but only applies to the next level
- of subroutine... the current subroutine (that detected the low stack
- condition) must be able to run in the old stack. Stacks are freed
- as they become unused.
-
- If for any reason DICE is unable to allocate a new stack, it will
- call the stack_abort() routine. If you do not define such a routine,
- the one from the library will be used (which abort()s the program).
-
- If you DO define a stack_abort() routine, then you must take one
- of two actions:
-
- (1) abort() or exit() the program
-
- (2) return (causes DICE to retry allocating the stack)
-
- If DICE is unable to reallocate the stack after (2), it will call
- stack_abort() again.
-
-
-